load("@prysm//tools/go:def.bzl", "go_library")
load("//tools/go:fuzz.bzl", "go_fuzz_test")
load("@com_github_prysmaticlabs_ethereumapis//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal")
load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")
load("@io_bazel_rules_go//go:def.bzl", "go_test")

# gazelle:ignore generated.ssz.go

config_setting(
    name = "fuzzing_enabled",
    values = {"define": "gotags=libfuzzer"},
)

ssz_gen_marshal(
    name = "ssz_generated_files",
    srcs = ["inputs.go"],
    includes = [
        "//proto/beacon/p2p/v1:go_default_library",
        "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
    ],
    objs = [
        "InputBlockWithPrestate",
    ],
)

IMPORT_PATH = "github.com/prysmaticlabs/prysm/fuzz"

COMMON_DEPS = [
    "//beacon-chain/state:go_default_library",
    "//shared/featureconfig:go_default_library",
    "@com_github_prysmaticlabs_go_ssz//:go_default_library",
    "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
] + SSZ_DEPS

COMMON_SRCS = [
    "common.go",
    "inputs.go",
    ":ssz_generated_files",
]

SRCS = COMMON_SRCS + glob(["*_fuzz.go"])

test_suite(
    name = "fuzz_tests",
    tags = ["manual"],
    tests = [
        ":block_fuzz_test_with_libfuzzer",
        ":rpc_status_fuzz_test_with_libfuzzer",
        ":state_fuzz_test_with_libfuzzer",
    ],
)

go_fuzz_test(
    name = "block_fuzz_test",
    srcs = [
        "block_fuzz.go",
    ] + COMMON_SRCS,
    corpus = "@sigp_beacon_fuzz_corpora//:current_mainnet_block_header",
    corpus_path = "external/sigp_beacon_fuzz_corpora/0-11-0/mainnet/block_header",
    func = "BeaconFuzzBlock",
    importpath = IMPORT_PATH,
    max_len = 30000000,
    deps = [
        "//beacon-chain/core/blocks:go_default_library",
        "//beacon-chain/core/state:go_default_library",
        "//fuzz/testing:go_default_library",
        "//shared/params:go_default_library",
        "//proto/beacon/p2p/v1:go_default_library",
        "//beacon-chain/operations/attestations:go_default_library",
        "//beacon-chain/p2p/testing:go_default_library",
        "//beacon-chain/sync:go_default_library",
        "//beacon-chain/db:go_default_library",
        "//beacon-chain/operations/voluntaryexits:go_default_library",
        "//beacon-chain/blockchain:go_default_library",
        "//beacon-chain/operations/slashings:go_default_library",
        "//beacon-chain/forkchoice/protoarray:go_default_library",
        "//shared/testutil:go_default_library",
        "@com_github_libp2p_go_libp2p_core//peer:go_default_library",
        "@com_github_libp2p_go_libp2p_pubsub//:go_default_library",
        "@com_github_libp2p_go_libp2p_pubsub//pb:go_default_library",
        "@com_github_sirupsen_logrus//:go_default_library",
        "//beacon-chain/p2p:go_default_library",
        "//beacon-chain/blockchain/testing:go_default_library",
        "//beacon-chain/cache:go_default_library",
        "//beacon-chain/state/stategen:go_default_library",
        "//shared/rand:go_default_library",
    ] + COMMON_DEPS,
)

go_fuzz_test(
    name = "rpc_status_fuzz_test",
    srcs = [
        "rpc_status_fuzz.go",
    ] + COMMON_SRCS,
    corpus = "rpc_status_corpus",
    corpus_path = "fuzz/rpc_status_corpus",
    func = "BeaconFuzzP2PRPCStatus",
    importpath = IMPORT_PATH,
    deps = [
        "//beacon-chain/p2p:go_default_library",
        "//beacon-chain/sync:go_default_library",
        "//beacon-chain/blockchain/testing:go_default_library",
        "//beacon-chain/sync/initial-sync/testing:go_default_library",
        "//beacon-chain/cache:go_default_library",
        "//proto/beacon/p2p/v1:go_default_library",
        "//shared/bytesutil:go_default_library",
        "@com_github_pkg_errors//:go_default_library",
        "@com_github_libp2p_go_libp2p//:go_default_library",
        "@com_github_libp2p_go_libp2p_core//host:go_default_library",
        "@com_github_libp2p_go_libp2p_core//peer:go_default_library",
        "@com_github_libp2p_go_libp2p_core//network:go_default_library",
        "@com_github_libp2p_go_libp2p_core//mux:go_default_library",
        "@com_github_sirupsen_logrus//:go_default_library",
    ] + COMMON_DEPS,
)

go_fuzz_test(
    name = "ssz_encoder_attestations_test",
    srcs = [
        "ssz_encoder_attestations_fuzz.go",
    ] + COMMON_SRCS,
    corpus = "@sigp_beacon_fuzz_corpora//:current_mainnet_block_header",
    corpus_path = "external/sigp_beacon_fuzz_corpora/0-11-0/mainnet/block_header",
    func = "SszEncoderAttestationFuzz",
    importpath = IMPORT_PATH,
    deps = [
        "//beacon-chain/p2p/encoder:go_default_library",
        "//shared/params:go_default_library",
        "//proto/beacon/p2p/v1:go_default_library",
    ] + COMMON_DEPS,
)

go_fuzz_test(
    name = "state_fuzz_test",
    srcs = [
        "state_fuzz.go",
    ] + COMMON_SRCS,
    corpus = "@sigp_beacon_fuzz_corpora//:0_11_0_mainnet_beaconstate",
    corpus_path = "external/sigp_beacon_fuzz_corpora/0-11-0/mainnet/beaconstate",
    func = "BeaconStateFuzz",
    importpath = IMPORT_PATH,
    max_len = 30000000,
    deps = [
        "//proto/beacon/p2p/v1:go_default_library",
        "//beacon-chain/core/state:go_default_library",
        "//beacon-chain/core/helpers:go_default_library",
        "//shared/params:go_default_library",
    ] + COMMON_DEPS,
)

go_library(
    name = "go_default_library",
    testonly = 1,
    srcs = [
        "common.go",
        "inputs.go",
        "rpc_status_fuzz.go",
        "ssz_encoder_attestations_fuzz.go",
        "state_fuzz.go",
        ":ssz_generated_files",  # keep
    ],
    importpath = "github.com/prysmaticlabs/prysm/fuzz",
    visibility = ["//visibility:public"],
    deps = [
        "//beacon-chain/blockchain:go_default_library",
        "//beacon-chain/blockchain/testing:go_default_library",
        "//beacon-chain/cache:go_default_library",
        "//beacon-chain/core/blocks:go_default_library",
        "//beacon-chain/core/helpers:go_default_library",
        "//beacon-chain/core/state:go_default_library",
        "//beacon-chain/db:go_default_library",
        "//beacon-chain/forkchoice/protoarray:go_default_library",
        "//beacon-chain/operations/attestations:go_default_library",
        "//beacon-chain/operations/slashings:go_default_library",
        "//beacon-chain/operations/voluntaryexits:go_default_library",
        "//beacon-chain/p2p:go_default_library",
        "//beacon-chain/p2p/encoder:go_default_library",
        "//beacon-chain/p2p/testing:go_default_library",
        "//beacon-chain/state:go_default_library",
        "//beacon-chain/state/stategen:go_default_library",
        "//beacon-chain/sync:go_default_library",
        "//beacon-chain/sync/initial-sync/testing:go_default_library",
        "//fuzz/testing:go_default_library",
        "//proto/beacon/p2p/v1:go_default_library",
        "//shared/bytesutil:go_default_library",
        "//shared/featureconfig:go_default_library",
        "//shared/params:go_default_library",
        "//shared/rand:go_default_library",
        "//shared/testutil:go_default_library",
        "@com_github_libp2p_go_libp2p_core//host:go_default_library",
        "@com_github_libp2p_go_libp2p_core//network:go_default_library",
        "@com_github_libp2p_go_libp2p_core//peer:go_default_library",
        "@com_github_libp2p_go_libp2p_pubsub//:go_default_library",
        "@com_github_libp2p_go_libp2p_pubsub//pb:go_default_library",
        "@com_github_libp2p_go_libp2p//:go_default_library",
        "@com_github_pkg_errors//:go_default_library",
        "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
        "@com_github_prysmaticlabs_go_ssz//:go_default_library",
        "@com_github_sirupsen_logrus//:go_default_library",
    ] + SSZ_DEPS,  # keep
)

go_library(
    name = "inputs",
    srcs = [
        "inputs.go",
        ":ssz_generated_files",  # keep
    ],
    importpath = "github.com/prysmaticlabs/prysm/fuzz",
    visibility = ["//visibility:public"],
    deps = [
        "//proto/beacon/p2p/v1:go_default_library",
        "@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
    ] + SSZ_DEPS,  # keep
)
